package com.hainatong.mvvmbase.base;


import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.hainatong.mvvmbase.loadsir.callback.Callback;
import com.hainatong.mvvmbase.loadsir.core.LoadService;
import com.hainatong.mvvmbase.loadsir.core.LoadSir;
import com.hainatong.mvvmbase.loadsir.layoutcallback.EmptyCallback;
import com.hainatong.mvvmbase.loadsir.layoutcallback.ErrorCallback;
import com.hainatong.mvvmbase.loadsir.layoutcallback.LoadingCallback;
import com.hainatong.mvvmbase.utils.ClassUtil;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

/**
 * 应用模块:fragment
 * <p>
 * 类描述: 基类fragment
 * <p>
 *
 * @author
 * @since 2020-01-27
 */
public abstract class BaseMvvmFragment<V extends ViewDataBinding, VM extends AndroidViewModel> extends Fragment
{
    // ViewModel
    protected VM viewModel;

    // 布局view
    protected V viewDataBinding;

    protected String mFragmentTag = this.getClass().getSimpleName();

    private LoadService mLoadService;

    //RxBus  取消订阅 关系时  使用
    private CompositeDisposable mCompositeDisposable;

    @Override
    public void onAttach(@NonNull Context context)
    {
        super.onAttach(context);
        //activity = (Activity) context;
        Log.d(mFragmentTag, " : onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        initParameters();
        Log.d(mFragmentTag,"onCreate");
    }

    /**
     * 初始化参数
     */
    protected void initParameters()
    {
    }
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        viewDataBinding =
                DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
        Log.d(mFragmentTag, " : onCreateView");
        //这里 要使用  loadSer 返回的 跟布局
        mLoadService = LoadSir.getDefault()
                .register( viewDataBinding.getRoot() , (Callback.OnReloadListener) v -> onRetryBtnClick());

        return mLoadService.getLoadLayout();
    }

    @Override
    public void onViewCreated(@NonNull View view,
                              @Nullable Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);
        initViewModel();
        if (null != viewModel && getBindingVariable() > 0)
        {
            viewDataBinding.setVariable(getBindingVariable(), viewModel);
            viewDataBinding.executePendingBindings();
        }
        Log.d(mFragmentTag, " : onViewCreated");
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        Log.d(mFragmentTag, " : onActivityCreated");
    }

    /**
     * 初始化ViewModel
     */
    private void initViewModel()
    {
        Class<VM> viewModelClass = ClassUtil.getViewModel(this);
        if (viewModelClass != null)
        {
            viewModel = new ViewModelProvider(this).get(viewModelClass);
        }
    }

    protected <T extends View> T getView(int id)
    {
        return (T) getView().findViewById(id);
    }

    /**
     * 布局
     */
    @LayoutRes
    public abstract int getLayoutId();


    /**
     * 获取参数
     */
    public abstract int getBindingVariable();

    /**
     * 失败重试,加载事件
     */
    protected abstract void onRetryBtnClick();


    private boolean isShowedContent = false;
    public void showContent()
    {
        if (null != mLoadService)
        {
            isShowedContent = true;
            mLoadService.showSuccess();
        }
    }

    public void showLoading()
    {
        if (null != mLoadService)
        {
            mLoadService.showCallback(LoadingCallback.class);
        }
    }

    public void showEmpty()
    {
        if (null != mLoadService)
        {
            mLoadService.showCallback(EmptyCallback.class);
        }
    }

    public void showFailure(String message)
    {
        if (null != mLoadService)
        {
            if (!isShowedContent)
            {
                mLoadService.showCallback(ErrorCallback.class);
            }
            else
            {
                //Toast.show(this, message);
            }
        }
    }


    @Override
    public void onResume()
    {
        super.onResume();
        Log.d(mFragmentTag, " : onResume");
    }

    @Override
    public void onPause()
    {
        super.onPause();
        Log.d(mFragmentTag, " : onPause");
    }

    @Override
    public void onDestroyView()
    {
        super.onDestroyView();
        Log.d(mFragmentTag, " : onDestroyView");
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        if (null != viewModel )
        {
            ((BaseViewModel)viewModel).onCleared();
        }
        if (this.mCompositeDisposable != null && !mCompositeDisposable.isDisposed())
        {
            this.mCompositeDisposable.clear();
        }
        Log.d(mFragmentTag, " : onDestroy");
    }

    @Override
    public void onDetach()
    {
        super.onDetach();
        if (null != viewModel )
        {
            //viewModel.onCleared();
        }
        Log.d(mFragmentTag, " : onDetach");

    }

    public void addSubscription(Disposable disposable)
    {
        if (this.mCompositeDisposable == null)
        {
            this.mCompositeDisposable = new CompositeDisposable();
        }
        this.mCompositeDisposable.add(disposable);
    }

    public void removeDisposable()
    {
        if (this.mCompositeDisposable != null && !mCompositeDisposable.isDisposed())
        {
            this.mCompositeDisposable.dispose();
        }
    }
}
